
import sys,os

# 16位数转换
def getUint16FromBytes(array, offset):
    tempU16 = 0
    tempU16 = array[offset + 1]
    tempU16 <<= 8
    tempU16 |= array[offset]
    return tempU16

# 各种条目的解析
# 字符串条目解析, 字符串的格式为
# 
def xmlStringDecode(array, offset):
    value =  getUint16FromBytes(array, offset)
    length = getUint16FromBytes(array, offset + 2)
    start = offset + 4
    stringNum = array[start]
    start += 1
    for i in range(stringNum):
        stringlen = array[start]
        start += 1
        string = array[start: start + stringlen].decode()
        start += stringlen
        print("0x%02X %s" % (i+1, string))
    
# pdo解码, 一个pdo的条目格式长度为8B, 格式为
# 主索引(2B)    子索引(1B)  字符串索引(1B)  数据类型(1B) 数据宽度(1B)    预留(2B) 
#   41 60       00          08              06          10              00 00    
# 数据类型 (SINT, USINT, INT, UINT, DINT, UDINT, LINT, ULINT)     
def xmlPdoDecode(array, offset):
    pass


addInfoList = (
    (0,     0,      "NOP",              None),
    (1,     9,      "Device Specific",  None),
    (10,    10,     "Strings",          xmlStringDecode),
    (20,    20,     "DataTypes",        None),
    (30,    30,     "General",          None),
    (40,    40,     "FMMU",             None),
    (41,    41,     "SM",               None),
    (50,    50,     "TxPdo",            None),
    (51,    51,     "RxPdo",            None),
    (60,    60,     "DC",               None),
    # (60,    2047,   "Reserve", None)
    (0x0800, 0x0FFF,"Vendor Specific", None)
    # (0x1000, 0xFFFF,"Reserve", None)
)

# 通过value值找到信息
def findInfoByValue(value):
    for info in addInfoList:
        if value >= info[0] and value <= info[1]:
            return info
    return None

# 打开文件
with open(sys.argv[1], "rb") as f:
    content = f.read()

counter = 0x80
while(counter < len(content)):
    value = getUint16FromBytes(content, counter)        # 获取
    info = findInfoByValue(value)                       # 查找匹配条目
    if info is not None:
        length = getUint16FromBytes(content, counter + 2)   # 获取长度
        logger.info("%-10s %3d words 0x%04X-0x%04X" % (info[2], length, counter, counter + 4 + length*2))
        
        # 执行解析函数
        if info[3] is not None:
            info[3](content, counter)
        counter += 4 + length * 2
    else:
        counter += 2

